#include "tokenroulette.h"

TokenRoulette::TokenRoulette()
{
}
void TokenRoulette::addWaitingRobot(Robot *robot){
    this->waitingRobots.push_back(robot);
}

Robot* TokenRoulette::getFirstOnList(){
    return this->waitingRobots.front();
}

Robot* TokenRoulette::getLongestPath(){
    int pathLength=0;
    Robot * robot;
    Robot * resultRobot=NULL;
    for(robot=waitingRobots.front();robot<waitingRobots.back();++robot){
        if (robot->countPath()>pathLength)
            resultRobot=robot;
    }
    return resultRobot;
}
Robot* TokenRoulette::getRandomized(){
    std::list<Robot*>::iterator it;
    it = this->waitingRobots.begin();
    int offset=rand()%waitingRobots.size();
    while(offset>0)
        it ++;
    std::cout<<offset;
    return (*it);
}

void TokenRoulette::removeFromList(Robot* robot){
    this->waitingRobots.remove(robot);
}

bool TokenRoulette::checkNumberOfRobots(){
    std::cout << "------------------------------------------------" << std::endl;
    std::list<Robot*>::iterator robotIt;
    for(robotIt=ws->robots.begin();
    robotIt!=ws->robots.end();++robotIt){
        if ((*robotIt)->path->isEmpty()){
            std::cout << "Robot " << (*robotIt)->getId() << " erased" << std::endl;
            (*robotIt)->occupiedCell->removeRobot((*robotIt)->getRobot());
            (*robotIt)->occupiedCell->removeGrant();
            robotIt = this->ws->robots.erase(robotIt);
        }
//        else
//            std::cout << "Robot " << (*robotIt)->getId() << " stays on the stage" << std::endl;
    }
    return !(ws->robots.empty());
}

//based on the getFirstOnList() selection method
void TokenRoulette::run(){

    //update cells for safety check
    //update waiting robots list

    std::list<Robot*>::iterator robotIt;

    for(robotIt=ws->robots.begin();robotIt!=ws->robots.end();++robotIt){

        Robot *robot = (*robotIt)->getRobot();
        if (robot->asked4NextCell()&&
            !this->isOnWaitingList(robot)&&
            (!robot->path->isEmpty())){
            waitingRobots.push_back(robot);   // tutaj dodajemy roboty na liste oczekujaca
        }
    }

    if (waitingRobots.size()){
        Robot* robot = this->getFirstOnList();
        if (ws->isNextStateSafe(robot)){
            std::cout<<"Next state of robot"<<robot->getId()<<" is safe."<<std::endl;
            robot->path->first()->printCell();
            std::cout<<"is granted for robot "<<robot->getId()<<std::endl;
            robot->grantAccessToNextCell();
            ws->printStage();
            removeFromList(robot);
            robot->move();
            //robot->path->first()->removeGrant();
//            std::cout<<"robot removed from waiting list"<<std::endl;
//            std::cout << "Number of remaining cells: " << robot->path->cells.size() << std::endl;
        }
        else{
            //remove the robot from the beginning of the queue
            //and put it at the very end of it

            std::cout<<"Next state of robot "<<robot->getId()<<" is not safe."<<std::endl;
            waitingRobots.pop_front();
            waitingRobots.push_back(robot);
        }
    }
    else
        std::cout<<"no robot waiting"<<std::endl;
}

bool TokenRoulette::isOnWaitingList(Robot *robot){
    std::list<Robot*>::iterator robotIt;
    for(robotIt=waitingRobots.begin();robotIt!=waitingRobots.end();++robotIt){
        if (robot==(*robotIt)->getRobot())return true;
    }
    return false;
}
